package smartcode;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.app.Dialog;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;

import com.aliang.auto.R;
import com.mumu.loading.MMLoading;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.TreeMap;

import app.auto.runner.base.DipUtil;
import app.auto.runner.base.InputMethodUtil;
import app.auto.runner.base.MapAdapter;
import app.auto.runner.base.MapContent;
import app.auto.runner.base.Util;
import app.auto.runner.base.framework.CrashHandler;
import app.auto.runner.base.intf.FunCallback;
import app.auto.runner.base.intf.ListBuilder;
import app.auto.runner.base.intf.MapBuilder;
import app.auto.runner.base.utility.ShareAlert;
import app.auto.runner.base.utility.SlideBottomUtil;
import app.auto.runner.base.utility.ToastUtil;
import app.auto.runner.base.utility.VerifyCode;
import app.auto.runner.base.widget.FloatLayout;
import app.auto.runner.func.Http;
import smartcode.util.ParaAlert;

import static android.view.View.GONE;

public class CodeActivity extends AppCompatActivity {

    public static MapBuilder animport = Import.build();

    public static Stack objectStack = new Stack();//最后一个返回值对象说明
    public static List<Stack> stacks = new ArrayList<Stack>(); //返回值对象 按行管理 索引器

    public static Map<String, String> vars = new TreeMap<String, String>(); //变量池
    //name clazzname

    //类型 变量名
    //1. popup
    //2. dialog


    private FloatLayout mFlowLayout;
    private BaseAdapter baseAdapter;

    private List<List<String>> list = new ArrayList<>();
    private MMLoading mmLoading;
    private Methods methods;


    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        String name = getIntent().getStringExtra("name");

        setContentView(R.layout.activity_code);
        ((TextView) findViewById(R.id.head)).setText(name.replace("...}", ""));

        new Thread() {
            @Override
            public void run() {
                getClasses();
                super.run();
            }
        }.start();

        initChildViews();
        CrashHandler.getInstance().init(this);

//        startActivity(new Intent().setClassName(getPackageName(), "smartcode.BodyActivity"));
    }
//      静态方法 简单构造器

    FloatLayout selectedFloatLayout;

    //判断静态对象
    //*静态方法//构造对象 ->赋值 / 对象方法
    //记录变量池
    //判断动态对象

    //赋值 //计算 //屏蔽静态右值
    private int line_position = 0;

    @RequiresApi(api = Build.VERSION_CODES.M)
    private void initChildViews() {

//        list.add(ListBuilder.build().add(" ; ").get());
//        list.add(ListBuilder.build().add(" ; ").get());
        findViewById(R.id.newone).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startAdd();

            }
        });


        findViewById(R.id.var).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                new Handler(Looper.getMainLooper(), new Handler.Callback() {
//
//                    @Override
//                    public boolean handleMessage(Message msg) {
//                        List m = MapBuilder.build().withMap(vars).splitMap("varname", "vartype");
//                        ParaAlert paraAlert;
//                        ListView listview = (paraAlert = ParaAlert.reservSin(ParaAlert.class, getContext()).alert((ListView) LayoutInflater.from(getContext()).inflate(R.layout.listview, null), m)).getListview();
//                        ShareAlert.get(ShareAlert.class, getContext()).create(listview).showDialog();
//                        paraAlert.setList(m);
//                        return false;
//                    }
//                }).sendEmptyMessage(0);
//                if (true) return;
                final List list = new ArrayList();
                for (String v1 : vars.keySet()) {
                    list.add(v1 + " : " + vars.get(v1));
                }
                ShareAlert.get(ShareAlert.class, v.getContext()).listAlert(list, new FunCallback() {
                    @Override
                    public void onCallback(Object result, Object object) {
                        super.onCallback(result, object);
                    }
                });
            }
        });
        findViewById(R.id.method).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                methods(objectStack.peek(), null, false);
            }
        });
        findViewById(R.id.returnvalue).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                returnvalue(null);
            }
        });
        markStack(0);
        findViewById(R.id.add).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startAdd();
            }
        });
        //赋值语句
        //方法语句
        // 匿名类语句
        // 类内调用
        // 自身调用
        // 成员调用
        //--------
        // 自身方法
        // 成员方法
        //成员赋值


        final ListView listView = findViewById(R.id.listview);
        baseAdapter = new BaseAdapter() {

            @Override
            public int getCount() {
                return list.size();
            }

            @Override
            public Object getItem(int position) {
                return list.get(position);
            }

            @Override
            public long getItemId(int position) {
                return 0;
            }

            @Override
            public View getView(final int position, View convertView, ViewGroup parent) {
                line_position = position;
                if (convertView == null) {
                    DipUtil.initCtx(getBaseContext());
                    int margin = DipUtil.fromDip(2f);
                    convertView = LayoutInflater.from(getBaseContext()).inflate(R.layout.activity_code_floatlayout, null);
                    ((FloatLayout) convertView.findViewById(R.id.floatlayout)).setLeftMargin(margin).setTopMargin(margin).setRightMargin(margin).setBottomMargin(margin);
                }
                final FloatLayout floatLayout = convertView.findViewById(R.id.floatlayout);
                ((FloatLayout) floatLayout).setText((List<String>) getItem(position));
                ((FloatLayout) floatLayout).setOnClickCallback(new FunCallback() {
                    @Override
                    public void onCallback(Object result, Object object) {
                        super.onCallback(result, object);
                        final TextView viewplus = (TextView) result;
                        int pos = (int) object;
                        if (viewplus.getText().toString().trim().equals("添加语句")) {
                            new Thread() {
                                @Override
                                public void run() {
                                    super.run();
                                    new Handler(Looper.getMainLooper(), new Handler.Callback() {
                                        @Override
                                        public boolean handleMessage(@NonNull Message msg) {
                                            if (viewplus.getParent() == null) {
                                                return false;
                                            }
                                            ((ViewGroup) viewplus.getParent()).performClick();


                                            return false;
                                        }


                                    }).sendEmptyMessageDelayed(0, 200);

                                }
                            }.start();

                        }
                    }
                });
                final View finalConvertView = convertView;
                convertView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (selectedFloatLayout == floatLayout) {
                            if (findViewById(R.id.bbar).getVisibility() == GONE) {
                                findViewById(R.id.bbar).setVisibility(View.VISIBLE);
                            } else {
                                line_position = position;
                                startAdd();

                            }
                        } else {
                            markStack(position);
                            selectedFloatLayout = (FloatLayout) floatLayout;
                            notifyDataSetChanged();
                        }
                    }
                });
                final View finalConvertView1 = convertView;

                convertView.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        ShareAlert.delAlert(CodeActivity.this, "删除", new FunCallback() {
                            @Override
                            public void onCallback(Object result, Object object) {
                                super.onCallback(result, object);
                                ((FloatLayout) finalConvertView1.findViewById(R.id.floatlayout)).setText(new ArrayList<String>());
                                list.remove(position);
                                if (position + 1 <= stacks.size()) {
                                    stacks.remove(position);
                                }
                                baseAdapter.notifyDataSetChanged();

                            }
                        });
                        return false;
                    }
                });
                if (floatLayout == selectedFloatLayout) {
                    convertView.setBackgroundResource(R.drawable.auto_background_rect_green);
                } else {
                    convertView.setBackgroundColor(getColor(R.color.transparent));
                }

//                if (position == 0) {
//                    if (selectedFloatLayout == null) {
//                        selectedFloatLayout = (FloatLayout) floatLayout;
//                        notifyDataSetChanged();
//                    }
//                }
                return convertView;
            }
        };
        listView.setAdapter(baseAdapter);


        findViewById(R.id.finish).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v1) {
                View v = findViewById(R.id.edit);
                if (!((TextView) v).getText().toString().isEmpty()) {
                    String str = ((TextView) v).getText().toString();
                    if (selectedFloatLayout.getText() == null) {
                        selectedFloatLayout.setText(ListBuilder.build().add(str).get());
                    } else {
                        selectedFloatLayout.addLast(str);
                    }
                    selectedFloatLayout.notifyChanged();
                    ((TextView) v).setText("");
                }
            }
        });

        View footer = LayoutInflater.from(getBaseContext()).inflate(R.layout.text_plus, null);
        listView.addFooterView(footer);
        footer.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                list.add(ListBuilder.build().add(" ; ").get());

                baseAdapter.notifyDataSetChanged();
                new Handler(Looper.getMainLooper()) {
                    @Override
                    public void handleMessage(@NonNull Message msg) {
                        super.handleMessage(msg);
                        ViewGroup v =
                                (ViewGroup) listView.getChildAt(listView.getChildCount() - 2);
                        if (v.getChildAt(0) instanceof FloatLayout) {
                            v.performClick();
                        }
                        if (findViewById(R.id.bbar).getVisibility() == GONE) {
                            findViewById(R.id.bbar).setVisibility(View.VISIBLE);
                        }
//                        new Handler(Looper.getMainLooper()) {
//                            @Override
//                            public void handleMessage(@NonNull Message msg) {
//                                super.handleMessage(msg);
//                                ViewGroup v =
//                                        (ViewGroup) listView.getChildAt(listView.getChildCount() - 2);
//                                if (v.getChildAt(0) instanceof FloatLayout) {
//                                    v.performClick();
//                                }
//                            }
//                        }.sendEmptyMessageDelayed(0, 50);
                    }
                }.sendEmptyMessageDelayed(0, 50);
//                listView.getChildAt(listView.getChildCount()-1).performClick();
            }
        });
    }

    private void syncFunStatus() {
        if (!objectStack.isEmpty()) {
            findViewById(R.id.newone).setVisibility(GONE);
        } else {
            findViewById(R.id.newone).setVisibility(View.VISIBLE);
        }
        if (!objectStack.isEmpty()) {
            findViewById(R.id.method).setVisibility(View.VISIBLE);
        } else {
            findViewById(R.id.newone).setVisibility(GONE);
        }
        if (!objectStack.isEmpty()) {
            findViewById(R.id.returnvalue).setVisibility(View.VISIBLE);
        } else {
            findViewById(R.id.returnvalue).setVisibility(GONE);
        }

    }

//    @Override
//    protected void onResume() {
//        super.onResume();
//        syncFunStatus();
//    }

    public void startAdd() {
        markStack(line_position);

        if (objectStack.isEmpty()) {
            addClass(true);

        } else {
            ShareAlert.get(ShareAlert.class, getContext()).setSlideOrPop(true).setListsearchEditEnabled(false).setOnShow(new FunCallback() {
                @Override
                public void onCallback(Object result, Object object) {
                    super.onCallback(result, object);
                    InputMethodUtil.showInput(getBaseContext(), ((EditText) findViewById(R.id.edit)));
                }
            })
                    .listAlert(ListBuilder.build().add("方法").add("返回值").get(), new FunCallback() {


                        @RequiresApi(api = Build.VERSION_CODES.M)
                        @Override
                        public void onCallback(Object result, Object object) {
                            super.onCallback(result, object);
                            SlideBottomUtil rtn = (SlideBottomUtil) getParam();

                            if (result.equals("方法")) {
                                methods(objectStack.peek(), null, false);
//                                            addAClz(objectStack.peek(), rtn, selectedFloatLayout, objectStack, baseAdapter, getContext());

                            } else if (result.equals("返回值")) {
                                returnvalue(null);
                            }
                            rtn.dismiss();
                        }
                    });
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    private boolean returnvalue(Dialog rtn) {
        if (selectedFloatLayout.getText().contains("= ")) {
            ToastUtil.live(getContext()).toast("已经有返回值了");
            if (rtn != null) {
                rtn.dismiss();
                rtn.cancel();
            }
            return true;
        }
        String var_name = "";
        Class clz = null;
        String writtenClzName = "";
        List base = ListBuilder.build().add("int").add("float").add("double").add("boolean").add("byte").add("Void").get();

//                                            if (objectStack.peek().toString().contains("[]")) {
//                                                String tmp = objectStack.peek().toString().replace("[]", "");
//                                                if (base.contains(tmp)) {
//                                                    writtenClzName = tmp + "Arr";
//                                                    var_name = writtenClzName.toLowerCase().substring(0, 1) + VerifyCode.getVerifycode3();
//                                                }
//                                            } else
        if (base.contains(objectStack.peek().toString())) {
            writtenClzName = objectStack.peek().toString();
            var_name = writtenClzName.toLowerCase().substring(0, 1) + VerifyCode.getVerifycode3();
        } else {


            try {
                clz = Class.forName(objectStack.peek().toString());
            } catch (Exception e) {
                CrashHandler.errorDialog(e);
                e.printStackTrace();
            }

            if (animport.get().containsValue(clz.getName())) {
                //存在这个类
                writtenClzName = clz.getSimpleName();
            } else {
                //不存在这个类
                //但是存在简写
                if (animport.get().containsKey(clz.getSimpleName())) {

                    writtenClzName = clz.getName();

                } else {
                    writtenClzName = clz.getSimpleName();
                    animport.add(clz.getSimpleName(), clz.getName());
                }
            }
            var_name = writtenClzName.toLowerCase();
        }

        selectedFloatLayout.addFirstNotified("= ", FloatLayout.TYPE_OPTEQUAL);
        selectedFloatLayout.addFirstNotified(var_name + " ", FloatLayout.TYPE_VARNAME);
        selectedFloatLayout.addFirstNotified(writtenClzName + " ", FloatLayout.TYPE_VARTYPE);
        vars.put(var_name, writtenClzName);
        return false;
    }

    private void markStack(int position) {
        if (position <= stacks.size() - 1) {

        } else {
            stacks.add(position, new Stack());
        }
        Stack stack = stacks.get(position);
        //java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
        objectStack = stack;
    }

    List<String> rawclasses;

    public void addClass(final boolean newObject) {
        showLoading();
//        dialog.getWindow().setLayout(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        new Thread() {
            @Override
            public void run() {
                super.run();
                getClasses();
                new Handler(Looper.getMainLooper(), new Handler.Callback() {
                    @Override
                    public boolean handleMessage(@NonNull Message msg) {
                        hideLoading();
                        ShareAlert.get(ShareAlert.class, getContext()).setSlideOrPop(true).setSearchEditHint("新建对象").listAlert(new ArrayList(rawclasses), new FunCallback() {
                            @Override
                            public void onCallback(Object clzName, Object object) {
                                super.onCallback(clzName, object);
                                methods(clzName, getParam(), newObject);
                                if (getParam() != null) {

                                    if (getParam() instanceof Dialog) {
                                        final Dialog clzes = ((Dialog) this.getParam());
                                        clzes.dismiss();
                                        clzes.cancel();
                                    } else if (getParam() instanceof PopupWindow) {
                                        final PopupWindow clzes = ((PopupWindow) this.getParam());
                                        clzes.dismiss();

                                    }

                                }

                            }


                        });

                        return false;
                    }
                }).sendEmptyMessage(0);
            }
        }.start();
        //


        //一个入口 在哪里输入

//        List rawclasses = getClassName(mp.toString(), false);

    }

    private void methods(Object clzName, Object clzes, boolean newObject) {
        methods = Methods.get(Methods.class, getContext());
        methods.setAnimport(animport);

        methods.setSlideOrPop(true).setResult(clzName).setClzes(clzes).setSelectedFloatLayout(selectedFloatLayout).setObjectStack(objectStack).setBaseAdapter(baseAdapter);
//                ShareAlert.shareAlert((Activity) getContext(), result.toString());
        Class clz = null;
        try {
            clz = Class.forName(clzName.toString());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        if (clz == null) {
            ToastUtil.live(this).toast("没有方法了");
            return;
        }
        ListBuilder listBuilder = ListBuilder.build();
        List staticmethodsRtn = new ArrayList();
        List staticmethods = new ArrayList();
        List dynmethods = new ArrayList();
        for (Method m : clz.getMethods()) {
            if (m.toGenericString().contains("public")) {

                if (m.toGenericString().contains("static")) {
                    if (newObject) {
                        if (m.getReturnType().getName().equals(clz.getName())) {
                            staticmethodsRtn.add(m);
                        } else {
                            staticmethods.add(m);
                        }
                    } else {
                        staticmethodsRtn.add(m);
                    }

                } else {
                    dynmethods.add(m);
                }
            }
        }
        if (newObject) {
            listBuilder.add(new ArrayList(Arrays.asList(clz.getConstructors())));
            listBuilder.add(staticmethodsRtn);
            listBuilder.add(staticmethods);
            methods.setGroup(ListBuilder.build().add("构造器").add("静态方法(返回对象)").add("静态方法").get());
        } else {
            listBuilder.add(staticmethodsRtn);
            listBuilder.add(dynmethods);
            methods.setGroup(ListBuilder.build().add("静态方法").add("public动态").get());
        }

        methods.setChilds(listBuilder.get());
        methods.addAClz(newObject);
    }

    private synchronized void getClasses() {
        if (rawclasses == null) {
            rawclasses = Util.getClassName(getContext());
        }
    }


    private Context getContext() {
        return this;
    }

    protected void showLoading() {
        if (mmLoading == null) {
            MMLoading.Builder builder = new MMLoading.Builder(this)
                    .setMessage("加载中...")
                    .setCancelable(false)
                    .setCancelOutside(true);
            mmLoading = builder.create();
        } else {
            mmLoading.dismiss();
            MMLoading.Builder builder = new MMLoading.Builder(this)
                    .setMessage("加载中...")
                    .setCancelable(false)
                    .setCancelOutside(true);
            mmLoading = builder.create();
        }
        mmLoading.show();
    }

    protected void showLoading(String msg) {
        if (mmLoading == null) {
            MMLoading.Builder builder = new MMLoading.Builder(this)
                    .setMessage(msg)
                    .setCancelable(false)
                    .setCancelOutside(true);
            mmLoading = builder.create();
        } else {
            mmLoading.dismiss();
            MMLoading.Builder builder = new MMLoading.Builder(this)
                    .setMessage(msg)
                    .setCancelable(false)
                    .setCancelOutside(false);
            mmLoading = builder.create();
        }
        mmLoading.show();
    }

    protected void hideLoading() {
        if (mmLoading != null && mmLoading.isShowing()) {
            mmLoading.dismiss();
        }
    }

    @Override
    public void finish() {
        super.finish();
        stacks.clear();
        objectStack.clear();
        animport.get().clear();
    }


}
